package com.xhx.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.TimeUnit;

/**
 * Redis 工具类（字符串与对象）
 */
@Service("redisUtils")
public class RedisUtils {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired(required = false)
    public void setRedisTemplate(RedisTemplate redisTemplate) {

        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);

//        RedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(); // 默认的序列化方式, 存储二进制字节码
//        redisTemplate.setValueSerializer(jdkSerializer);
//        redisTemplate.setHashValueSerializer(jdkSerializer);

        this.redisTemplate = redisTemplate;
    }

    @Autowired(required = false)
    public void setStringRedisTemplate(StringRedisTemplate redisTemplate) {

        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);

        this.stringRedisTemplate = redisTemplate;
    }

    // region [ 通用项 ]

    /**
     * 判断键是否存在
     *
     * @param key 参数
     * @return
     */
    public Boolean exists(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    // endregion

    //region [ 字符串 ]

    /**
     * 设置键，长存
     *
     * @param key   键名
     * @param value 键值
     * @return true成功/false失败
     */
    public boolean setRedisString(String key, String value) {
        try {
            stringRedisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 设置键，定存
     *
     * @param key      键名
     * @param value    键值
     * @param expriese 时长秒 7200
     * @return true成功/false失败
     */
    public boolean setRedisString(String key, String value, int expriese) {
        try {
            if (expriese > 0) {
                stringRedisTemplate.opsForValue().set(key, value, expriese, TimeUnit.SECONDS);
            } else {
                setRedisString(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 设置键，定存
     *
     * @param key      键名
     * @param value    键值
     * @param expriese 时长秒 7200
     * @param timeUnit 单位 TimeUnit.SECONDS
     * @return true成功/false失败
     */
    public boolean setRedisString(String key, String value, int expriese, TimeUnit timeUnit) {
        try {
            if (expriese > 0) {
                stringRedisTemplate.opsForValue().set(key, value, expriese, timeUnit);
            } else {
                setRedisString(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获得键值 字符串
     *
     * @param key 参数
     * @return
     */
    public String getRedisString(String key) {
        return key == null ? null : stringRedisTemplate.opsForValue().get(key);
    }

    //endregion

    //region [ 对象 ]

    /**
     * 设置键，长存
     *
     * @param key   键名
     * @param value 键值
     * @return true成功/false失败
     */
    public boolean setRedis(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 设置键，定存
     *
     * @param key      键名
     * @param value    键值
     * @param expriese 时长秒 7200
     * @return true成功/false失败
     */
    public boolean setRedis(String key, Object value, int expriese) {
        try {
            if (expriese > 0) {
                redisTemplate.opsForValue().set(key, value, expriese, TimeUnit.SECONDS);
            } else {
                setRedis(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 设置键，定存
     *
     * @param key      键名
     * @param value    键值
     * @param expriese 时长秒 7200
     * @param timeUnit 单位 TimeUnit.SECONDS
     * @return true成功/false失败
     */
    public boolean setRedis(String key, Object value, int expriese, TimeUnit timeUnit) {
        try {
            if (expriese > 0) {
                redisTemplate.opsForValue().set(key, value, expriese, timeUnit);
            } else {
                setRedis(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获得键值
     *
     * @param key 参数
     * @return
     */
    public Object getRedis(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    //endregion
}
